//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
// Core Special Function Registers for M8051W/EW
// 
// $Log: m3s008dy.v,v $
// Revision 1.9  2001/11/20
// First checkin of version 2 features and name change
//
// Revision 1.2  2001/10/31
// First parsable verilog for EW
//
// Revision 1.1.1.1  2001/07/17
// Re-imported E-Warp from Farnham filesystem
//
// Revision 1.8  2000/10/24
// Multiplier rewritten to improve power consumption.
// Code changes for Leonardo (ECN01372).
// Code changes for formal verification tools (ECN01410).
// MOVX @Ri page address controllable from PORT2I if I/O ports ommitted (ECN01387).
//
// Revision 1.7  2000/02/10
// Redundancy reduced for code coverage
//
// Revision 1.6  2000/02/05
// Name change repercussions
//
// Revision 1.5  2000/02/01
// Configuration parameter names standardised
//
// Revision 1.4  2000/01/06
// PROGA no longer cleared during idle mode.
// Minor code tidying up.
//
// Revision 1.3  1999/12/08
// Eliminate user instruction during state transition from interrupt service to
// debug state.
// RTL clean up of redundant declarations and sensitvity list entries.
//
// Revision 1.2  1999/11/30
// More debug changes.
//
// Revision 1.1.1.1  1999/10/28
// "initialization and source check-in for m8051e"
//
// Revision 1.1  1999/10/22
// Initial revision
//
////////////////////////////////////////////////////////////////////////////////

`include "m8051w_defs.v"
`include "m8051w_cfg.v"

module m3s008dy (ACC, B, PSW, WRITE_PSW, REG_RESULT, ACC_RESULT, B_RESULT,
//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
                 CARRY_RESULT, AUX_CARRY_RESULT, OVERFLOW_RESULT, SFR_WRITE_EN,
                 SFR_CON, STATE, LAST_CYC, INTERNAL_WAIT, CCLK, INT_RESET);

  output [7:0] ACC, B, PSW;
  output       WRITE_PSW;

  input  [7:0] ACC_RESULT, B_RESULT;
  input  [7:1] REG_RESULT;
  input        CARRY_RESULT, AUX_CARRY_RESULT, OVERFLOW_RESULT;
  input  [2:0] SFR_WRITE_EN;
  input  [6:0] SFR_CON;
  input  [2:0] STATE;
  input        LAST_CYC;
  input        INTERNAL_WAIT;
  input        CCLK, INT_RESET;

  reg    [7:0] L_ACC, B, PSW;
  reg          WRITE_ACC, WRITE_B, WRITE_PSW, WRITE_CARRY, WRITE_AUX_CARRY;
  reg          WRITE_OVERFLOW;

  // The default time for writing an SFR is at the end of the instruction.
  // However the accumulator is written midway through cycle two during
  // MOVX and MOVC instructions, signalled by SFR_CON[1].
  // Many instructions operate on the accumulator intrinsically, without
  // generating an SFR address.  These are signalled by SFR_CON[0] = 1;
  // Multiply and divide instructions have an intrinsic effect on B, signalled
  // by SFR_CON[2].

  // SFR_CON |   Function
  // -----------------------------------------------------
  //    0    |  load accumulator at end of last cycle
  //    1    |  load accumulator at end of cycle 2 phase 1
  //    2    |  load B register
  //    3    |  load carry flag
  //    4    |  load auxilliary carry flag
  //    5    |  load overflow flag
  //    6    |  load accumulator from external data memory

  always @(SFR_WRITE_EN or SFR_CON or STATE or LAST_CYC)
  begin: p_write_ens

`ifdef muxed_pxram
    WRITE_ACC   <= (SFR_WRITE_EN[0] || SFR_CON[0]) && `CLP2                  ||
                    SFR_CON[6] && `C1P2                                      ||
                    SFR_CON[1] && `C2P1;
`else
    WRITE_ACC   <= (SFR_WRITE_EN[0] || SFR_CON[0] || SFR_CON[6]) && `CLP2    ||
                    SFR_CON[1] && `C2P1; 
`endif
    WRITE_B     <= SFR_WRITE_EN[1] || SFR_CON[2] && LAST_CYC && STATE[0];
    WRITE_PSW   <= SFR_WRITE_EN[2];
    WRITE_CARRY <= SFR_WRITE_EN[2] || SFR_CON[3] && LAST_CYC && STATE[0];
    WRITE_AUX_CARRY <= SFR_WRITE_EN[2] || SFR_CON[4] && STATE[0];
    WRITE_OVERFLOW  <= SFR_WRITE_EN[2] || SFR_CON[5] && LAST_CYC && STATE[0];

  end

  always @(posedge CCLK)
  begin: p_core_sfrs
    if (INT_RESET) begin
      L_ACC <= 8'h00;
      B   <= 8'h00;
      PSW <= 8'h00;
    end
    else if (~INTERNAL_WAIT) begin
      PSW[0] <= ^L_ACC;
      if (WRITE_ACC) begin
        L_ACC <= ACC_RESULT;
        end
      if (WRITE_B)
        B   <= B_RESULT;
      if (WRITE_PSW) begin
        PSW[5:3] <= REG_RESULT[5:3];
        PSW[1] <= REG_RESULT[1];
      end
      if (WRITE_CARRY)
        PSW[7] <= SFR_CON[3]? CARRY_RESULT: REG_RESULT[7];
      if (WRITE_AUX_CARRY)
        PSW[6] <= SFR_CON[4]? AUX_CARRY_RESULT: REG_RESULT[6];
      if (WRITE_OVERFLOW)
        PSW[2] <= SFR_CON[5]? OVERFLOW_RESULT: REG_RESULT[2];
    end
  end

  assign ACC = L_ACC;
 
endmodule
